/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package panaderialabaguette;
import excepciones.CamposVaciosExcepcion;
import excepciones.AdministradorExcepcion;
import excepciones.CodigoProductoExcepcion;
import excepciones.ContraseñaIncorrectaExcepcion;
import excepciones.DniExcepcion;
import excepciones.DniFormatoIncorrectoExcepcion;
import excepciones.DniLongitudInferiorExcepcion;
import excepciones.DniLongitudSuperiorExcepcion;
import excepciones.EfectivoIncorrectoExcepcion;
import excepciones.EfectivoInsuficienteExcepcion;
import excepciones.EfectivoVacioExcepcion;
import excepciones.EmpleadoExcepcion;
import excepciones.GerenteExcepcion;
import excepciones.NombreProductoExcepcion;
import excepciones.NombreUsuarioExcepcion;
import excepciones.NumeroFormatoIncorrectoExcepcion;
import excepciones.PrecioProductoExcepcion;
import excepciones.StockExcepcion;
import excepciones.TicketAnuladoExcepcion;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import panaderialabaguette.vista.VistaGestionEmpleados;
import panaderialabaguette.vista.VistaLaBaguette;
import panaderialabaguette.vista.VistaUsuario;


/**
 *
 * @author ESPINOZA-MORENO
 */
public class Panaderia {

    private final static String DIRECCION = "San Martin 249";
    private final static String TELEFONO = "0303456";
    private final static String CUIT = "01-15615645-2";
    private final static String RAZON_SOCIAL = "La Baguette";

    //Variables utilizadas para verificar si hay operaciones en curso
    private static boolean hayOperacionEnCurso;
    private static boolean hayVentaEnCurso;
    private static JFrame ventanaActiva;

    // Variable que identifica el empleado logueado en el Sistema
    private Empleado empleado;

    // Variables para implementar Model - View - Controller
    private static Panaderia panaderia;
    private PanaderiaListener panaderiaListener;

    //Constructor de la clase
    public Panaderia() {
        this.panaderia = this;
    }

    public static Panaderia getPanaderia() {
        return panaderia;
    }

    public Empleado getEmpleado() {
        return empleado;
    }

    public void setEmpleado(Empleado empleado) {
        this.empleado = empleado;
    }

    public void agregarPanaderiaListener(PanaderiaListener panaderiaListener){
        this.panaderiaListener = panaderiaListener;  
    }

    /****************************************************************************
     *  Métodos de Interfáz Gráfica,implementados en VistaLaBaguette            *
     * **************************************************************************
     */

    public void crearVentanaPrincipal(){
        new VistaLaBaguette().setVisible(true);
    }

    public void crearMenuPrincipal(){
        this.panaderiaListener.dibujarMenuPrincipal(this.getEmpleado());
    }

    public void ocultarLogIn() {
        this.panaderiaListener.dibujarOcultarLogIn();
    }

    public void mostrarLogIn() {

        this.panaderiaListener.dibujarMostrarLogIn(this.getEmpleado());
    }

    public void crearMenuNuevoUsuario(){
        this.panaderiaListener.dibujarMenuNuevoUsuario();
    }

    public void crearMenuNuevaVenta(){
       this.panaderiaListener.dibujarMenuNuevaVenta();
    }

    public void crearMenuGestionProductos(){
        this.panaderiaListener.dibujarMenuGestionProductos();
    }

    public void crearMenuGestionPedidos(){
        this.panaderiaListener.dibujarMenuGestionPedidos();
    }

    public void crearMenuGestionStock(){
        this.panaderiaListener.dibujarMenuGestionStock();
    }

    public void crearMenuGestionClientes(){
        this.panaderiaListener.dibujarMenuGestionClientes();
    }

    public void crearMenuGestionDevoluciones(){
        this.panaderiaListener.dibujarMenuGestionDevoluciones();
    }

    public void crearMenuGestionCtaCte(){
        this.panaderiaListener.dibujarMenuGestionCtaCte();
    }

    public void crearMenuGestionListados(){
        this.panaderiaListener.dibujarMenuGestionListados();
    }

    public void crearMenuGestionEmpleados() {
        this.panaderiaListener.dibujarMenuGestionEmpleados();
    }

    public void mostrarMenuGerente(){
        this.panaderiaListener.dibujarMenuGerente();
    }

    public void mostrarMenuAdministrador(){
        this.panaderiaListener.dibujarMenuAdministrador();
    }

    public void mostrarMenuEmpleadoDeVentas(){
        this.panaderiaListener.dibujarMenuEmpleadoDeVentas();
    }

    public void crearMenuConfiguracion(){
        this.panaderiaListener.dibujarMenuConfiguracion();
    }

    public void crearVentanaGuardarExcel(JTable tabla){
        this.panaderiaListener.dibujarVentanaGuardarExcel(tabla);
    }

    public void crearVentanaGrafico(JTable tabla){
        this.panaderiaListener.dibujarVentanaGrafico(tabla);
    }


     /***************************************************************************
     *  Fin métodos de interfaz gráfica                                         *
     * **************************************************************************
     */

    /****************************************************************************
     *  Métodos para manipular BASE DE DATOS                                 *
     * **************************************************************************
     */

    public void loginEmpleado(String nombre_usuario,String password){

        ResultSet rs = null;
        Conexion x = new Conexion() ;

        if ( validarCamposLogin(nombre_usuario,password) == false )
            return;

        x.estableceConexion();
        try {
            rs = x.obtenerTupla("empleado","nombre_usuario", nombre_usuario,"nombre_usuario");
            if (rs.next())
            {
                if (rs.getString(3).equals(password))
                {
                    Empleado empleado = new Empleado(Integer.parseInt(rs.getString(1)),rs.getString(2),rs.getString(3),rs.getString(4),rs.getString(5),rs.getString(6),rs.getString(7),rs.getString(8),rs.getString(9));
                    this.setEmpleado(empleado);
                    this.ocultarLogIn();
                    this.crearMenuPrincipal();
                }
                else
                {
                    JOptionPane.showMessageDialog(null, "La contraseña no es correcta...\nIngrese su contraseña nuevamente", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
            else
            {
                JOptionPane.showMessageDialog(null, "El usuario no existe...\nVerifique el nombre de usuario ingresado.", "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
        catch(Exception e){
            if (e instanceof SQLException)
            {
                  System.out.println("hubo excepcion SQL" );
            }
            else
            {
                System.out.println("hubo otro tipo de excepcion"+e.getMessage() );
            }
        }
    }

    public void crearClienteMayorista(VistaLaBaguette vista){
        String nombre = vista.campoRazonSocial.getText().trim();
        String cuit = vista.campoCuit.getText().trim();
        String calle = vista.campoCalleCliente.getText().trim();
        String nro = vista.campoNroCliente.getText().trim();
        String depto = vista.campoDeptoCliente.getText().trim();
        String piso = vista.campoPisoCliente.getText().trim();
        String titular = vista.campoTitular.getText().trim();
        String localidad = vista.campoLocalidad.getText().trim();
        String email = vista.campoEmail.getText().trim();
        String telefono = vista.campoTel.getText().trim();

        if ( this.validarFormularioClienteMayorista(vista) == false )
               return;
        else
        {
            if (depto.isEmpty() && piso.isEmpty() )
            {
                piso = null;
                depto = " ";
            }

            if ( email.isEmpty() )
                 email = " ";

        }

        Conexion x = new Conexion();
        ResultSet rs = null;
        x.estableceConexion();

        try {
               int id_cliente = new Integer(x.obtenerID("id_cliente","cliente"))+1;
               x.crearRegistro(id_cliente,nombre,titular,cuit,calle,nro,depto,piso,localidad,email,telefono);
               JOptionPane.showMessageDialog(null,"Se creo un nuevo cliente...","OK",1);
        }
        catch (Exception e)
        {
            if ( e instanceof SQLException)
            {
                 JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados"+e.getMessage(),"ERROR",2);
            }
            else
            {
                 JOptionPane.showMessageDialog(null,"Hubo un error al intentar crear el cliente...\nVerifique los datos ingresados","ERROR",2);
            }
        }

        // Esta linea cierra la conexion con la base de datos
        x.cierraConexion();
    }

    public void crearClienteMinorista(VistaLaBaguette vista){
        
        String nombre = vista.campoNYA.getText().trim();
        String dni = vista.campoDNI.getText().trim();
        String calle = vista.campoCalle.getText().trim();
        String nro = vista.campoNro.getText().trim();
        String depto = vista.campoDepto.getText().trim();
        String piso = vista.campoPiso.getText().trim();
        String telefono = vista.campoTelefono.getText().trim();


        if ( this.validarFormularioCliente(vista) == false )
               return;
        else
        {
            if (depto.isEmpty() && piso.isEmpty())
            {
                piso = null;
                depto = " ";
            }
        }

        Conexion x = new Conexion();
        ResultSet rs = null;
        x.estableceConexion();
        

        try {
               int id_cliente = new Integer(x.obtenerID("id_cliente","cliente"))+1;
               x.crearRegistro(id_cliente,nombre,dni,calle,nro,depto,piso,telefono);
               JOptionPane.showMessageDialog(null,"Se creo un nuevo cliente...","OK",1);
        } 
        catch (Exception e)
        {
            if ( e instanceof SQLException)
            {
                 JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados"+e.getMessage(),"ERROR",2);
            }
            else
            {
                 JOptionPane.showMessageDialog(null,"Hubo un error al intentar crear el cliente...\nVerifique los datos ingresados","ERROR",2);

            }
        }
        
        // Esta linea cierra la conexion con la base de datos
        x.cierraConexion();
    }

    public void crearEmpleado(VistaUsuario vistaUsuario){
        int dni;
        String contraseña = null;
        String funcion = null;
        String nombreUsuario = null;
        String calle = null;
        Integer numero = null;
        String depto = null;
        String piso = null;
        String telefono = null;

        if( this.validarCamposCrearEmpleado(vistaUsuario) == false )
            return;

        try{
            dni = this.validarDNI(vistaUsuario);
            nombreUsuario = this.validarUsuario(vistaUsuario);
            funcion = this.validarFuncion(vistaUsuario.jComboBox1.getSelectedItem().toString());
            contraseña = this.validarContraseña(vistaUsuario);
            calle = vistaUsuario.calle.getText().trim();
            numero = this.validarNumeroCalle(vistaUsuario);
            depto = vistaUsuario.depto.getText().trim().toUpperCase();
            piso = vistaUsuario.piso.getText().trim();
            telefono = vistaUsuario.telefono.getText().trim();
            Conexion x = new Conexion() ;   // esta linea establece la conexion con la base de datos
            x.estableceConexion();

            if ( depto.isEmpty() && piso.isEmpty() )
                x.crearRegistro(dni,nombreUsuario,contraseña,funcion,calle,numero.toString(),telefono);
            else
                x.crearRegistro(dni,nombreUsuario,contraseña,funcion,calle,numero.toString(),depto,piso,telefono);

            Empleado empleado = new Empleado(dni,nombreUsuario,contraseña,funcion,calle,numero.toString(),depto,piso,telefono);
            JOptionPane.showMessageDialog(vistaUsuario,"Se creo un nuevo usuario...","OK",1);
            vistaUsuario.limpiarFormularios();
            x.cierraConexion();
        }
        catch (Exception e){
            if (e instanceof EmpleadoExcepcion){
                JOptionPane.showMessageDialog(vistaUsuario,e.getMessage()+"\nVerifique los datos ingresados.","ERROR",2);
            }
         }

    }

    public void modificarEmpleado(VistaGestionEmpleados vista) {



        if (vista.jTable1.getValueAt(0,0) == null)
        {
            JOptionPane.showMessageDialog(vista,"No se selecciono ningún empleado...\nSeleccione el empleado que desea modificar de la lista de usuarios del sistema.","ERROR",2);
            return;
        }
        
        String dni = vista.jTable1.getValueAt(0,0).toString();
        String nombre_usuario = vista.jTable1.getValueAt(0,1).toString();
        String tipo_usuario = vista.jTable1.getValueAt(0,2).toString();
        String calle = vista.jTable1.getValueAt(0,3).toString();
        String numero = vista.jTable1.getValueAt(0,4).toString();
        String telefono = vista.jTable1.getValueAt(0,7).toString();

        if ( (vista.jTable1.getValueAt(0,5) == null ) && !(vista.jTable1.getValueAt(0,6) == null) || !(vista.jTable1.getValueAt(0,5) == null) && (vista.jTable1.getValueAt(0,6) == null))
        {
             JOptionPane.showMessageDialog(vista, "El campo de piso o departamento están vacios. Por favor verifiquelo, y vuelva a intentarlo nuevamente", "ERROR", 2);
             return;
        }

        Conexion x = new Conexion() ;
        x.estableceConexion();
        try {
            String funcion = this.validarFuncion(tipo_usuario);
            if ((vista.jTable1.getValueAt(0,5) == null) && (vista.jTable1.getValueAt(0,6) == null))
            {
                x.modificarRegistro(Integer.parseInt(dni),nombre_usuario,funcion,calle,numero,telefono);
            }
            else
            {
                x.modificarRegistro(Integer.parseInt(dni),nombre_usuario,funcion,calle,numero,vista.jTable1.getValueAt(0,5).toString().toUpperCase(),vista.jTable1.getValueAt(0,6).toString(),telefono);
            }
            JOptionPane.showMessageDialog(vista,"El empleado se modifico con exito...","OK",1);
            vista.cargarUsuarios();
            DefaultTableModel datos = (DefaultTableModel) vista.jTable1.getModel();
            datos.removeRow(datos.getRowCount()-1);
            String [] data = {"","","","","","","",""};
            datos.addRow(data);
            vista.jTable1.setEnabled(false);
        }
        catch (Exception ex) {
            if ( ex instanceof SQLException )
                JOptionPane.showMessageDialog(vista,"Hubo un problema al intentar modificar el empleado...\nEl dni no puede ser modificado"+ex.getMessage()+" "+ex.getClass(),"ERROR",2);
            else
                JOptionPane.showMessageDialog(vista,ex.getMessage(),"ERROR",2);
        }
        x.cierraConexion();
    }

    public void eliminarEmpleado(VistaGestionEmpleados vista){

      ResultSet rs = null;
      Conexion x = new Conexion() ;
      x.estableceConexion();

      try{
            rs = x.obtenerTupla("empleado","nombre_usuario",vista.jTable1.getValueAt(0,1).toString());
            if (rs.next())
            {
                int opcion;
                opcion = JOptionPane.showConfirmDialog(vista, "Está a punto de eliminar el empleado\nDNI: "+rs.getString(1)+"\nNombre de usuario: "+rs.getString(2)+"\nTipo de empleado: "+rs.getString(4)+"\nEstá seguro que quiere eliminarlo?", "Cuidado!", JOptionPane.YES_NO_OPTION);
                if (opcion == 0)
                {
                    try
                    {
                        x.eliminarRegistro("empleado","dni",Integer.parseInt(vista.jTable1.getValueAt(0,0).toString()));
                        JOptionPane.showMessageDialog(vista, "El empleado ha sido eliminado...", "OK",1);
                        vista.cargarUsuarios();
                        DefaultTableModel datos = (DefaultTableModel) vista.jTable1.getModel();
                        datos.removeRow(datos.getRowCount()-1);
                        vista.jTable1.setEnabled(false);
                        String [] data = {"","","","","","","",""};
                        datos.addRow(data);
                    }
                    catch (Exception e)
                    {
                        if (e instanceof SQLException)
                        {
                            JOptionPane.showMessageDialog(vista,"Hubo un problema al intentar eliminar...\n"+e.getMessage(),"ERROR",2);
                        }
                        else
                        {
                            JOptionPane.showMessageDialog(vista,"Hubo un problema al eliminar el socio...\nEl tipo de dato ingresado no es correcto","ERROR",2);
                        }
                    }
                }
            }
            else
            {
                JOptionPane.showMessageDialog(vista, "No existe el socio... \nVerifique el DNI ingresado.", "ERROR",2);
            }

        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(vista,"No se selecciono ningún empleado...\nSeleccione el empleado que desea eliminar de la lista de usuarios del sistema.","ERROR",2);
        }
    }
    /**
     *
     * @param codigo
     * @param nombre
     * @param descripcion
     * @param precio_unitario
     * @param unidad
     * @param stock
     */
    public void crearProducto(String codigo, String nombre,String descripcion, String precio_unitario, String unidad, String stock) 
    {
        Conexion x = new Conexion();
        ResultSet rs = null;
        x.estableceConexion();

        
    
        try {
            rs = x.obtenerTupla("producto","id_producto",codigo);
            if (rs.next()) {
                JOptionPane.showMessageDialog(null,"El producto ya existe...\nVerifique el código ingresado","ERROR",2);

            } else {

                try {
                    x.crearRegistro(Integer.parseInt(codigo),nombre,descripcion,precio_unitario,unidad,stock);
                    JOptionPane.showMessageDialog(null,"Se creo un nuevo producto...","OK",1);
                } catch (Exception e) {
                    if ( e instanceof SQLException) {
                        JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
                    } else {
                        JOptionPane.showMessageDialog(null,"Hubo un error al intentar crear el producto...\nVerifique los datos ingresados","ERROR",2);
                    }
                }
            }
        } catch (Exception ex) {
            if( ex instanceof SQLException)
                JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
            else
                System.out.println("hubo otro tipo de excepciones "+ex.getMessage() );
        }
        // Esta linea cierra la conexion con la base de datos
        x.cierraConexion();
    }



    //retorna verdadero si los campos obligatorios del producto están vacios, en caso contrario falso
    public void validarProducto(String codigo, String nombre, String precio, String stock) throws Exception
    {
        try{
            this.validarCamposProducto(codigo,nombre,precio,stock);
            this.validarCodigo(codigo);
            this.validarNombreProducto(nombre);
            this.validarPrecio(precio);
            this.validarStock(stock);
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    public void validarCamposProducto(String codigo, String nombre, String precio, String stock) throws Exception{

        if ( codigo.equals("") || nombre.equals("") || precio.equals("") || stock.equals(""))
        {
            throw new CamposVaciosExcepcion("Hay campos que están vacíos, por favor verifíquelos");
        }

    }
    
    public void validarPrecio(String precio) throws Exception
    {
        try
        {
            if( Float.parseFloat(precio) < 0 )
                throw new PrecioProductoExcepcion("El precio es un nro menor a 0.");
        }
        catch(Exception e)
        {
            if (e instanceof PrecioProductoExcepcion)
                throw e;
            else
                throw new PrecioProductoExcepcion("El precio debe ser un número.");
        }
    }


    public void validarStock( String stock) throws Exception
    {
        try
        {
            if( Float.parseFloat(stock) <= 0 )
                throw new StockExcepcion("El número del stock debe ser mayor a 0.");
         }
        catch(Exception e)
        {
            if (e instanceof StockExcepcion)
                throw e;
            else
                throw new StockExcepcion("El stock debe ser un número.");
        }
    }

    public void validarCodigo( String codigo) throws Exception
    {
        final int MAX_CODIGO = 10000;
        final int MIN_CODIGO = 0;

        try
        {
            int num_cod =  Integer.parseInt(codigo);
            if( num_cod < MIN_CODIGO || num_cod > MAX_CODIGO)
                throw new CodigoProductoExcepcion("El código del producto debe ser un número entre 1 y 10000");
                
        }
        catch(Exception e)
        {
            if (e instanceof CodigoProductoExcepcion)
                throw e;
            else
                throw new CodigoProductoExcepcion("El código debe ser un número entero.");
        }
    }

     public void validarNombreProducto( String nombre) throws Exception
    {
        try
        {
            Integer.parseInt(nombre);
            throw new NombreProductoExcepcion("El nombre del producto no debe ser un número u otro caracter.");
        }
        catch(Exception e)
        {
            if (e instanceof NombreProductoExcepcion)
                throw e;
        }
    }

    public void modificarProducto(String codigo, String nombre,String descripcion, String precio, String unidad, String stock){
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try {
            x.modificarRegistroProducto(Integer.parseInt(codigo),nombre,descripcion,precio,unidad,stock);
            JOptionPane.showMessageDialog(null,"El producto se modifico con exito...","OK",1);
        }
        catch (Exception ex) {
                JOptionPane.showMessageDialog(null,"Hubo un problema al intentar modificar el producto...\nEl codigo de producto no puede ser modificado"+ex.getMessage(),"ERROR",2);
        }
        x.cierraConexion();
    }

    public void eliminarProducto(String codigo){
        ResultSet rs = null;
        Conexion x = new Conexion() ;
        x.estableceConexion();

        try{
            rs = x.obtenerTupla("producto","id_producto",codigo);
            if ( rs.next() )
            {
                int opcion;
                opcion = JOptionPane.showConfirmDialog(null,"Está a punto de eliminar el producto\nCódigo: "+rs.getString(1)+"\nNombre: "+rs.getString(2)+"\nDescripción: "+rs.getString(3)+"\nEstá seguro que quiere eliminarlo?", "Cuidado!", JOptionPane.YES_NO_OPTION);
                if ( opcion == 0 )
                {
                    try
                    {
                        x.eliminarRegistro("producto","id_producto",Integer.parseInt(codigo) );
                        JOptionPane.showMessageDialog(null,"El producto ha sido eliminado...", "OK",1);
                    }
                    catch (Exception e)
                    {
                        //Estas excepciones no tienen sentido, porque nunca vamos a entrar aca..
                        if (e instanceof SQLException)
                        {
                            JOptionPane.showMessageDialog(null,"El producto solicitado no existe... \nVerifique el código ingresado.","ERROR",2);
                        }
                        else
                        {
                            JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nEl tipo de dato ingresado no es correcto","ERROR",2);
                        }
                    }
                }
            }
            else
            {
                JOptionPane.showMessageDialog(null,"El producto solicitado no existe... \nVerifique el código ingresado.", "ERROR",2);
            }
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null,"Para eliminar un producto debe ingresar el código...\nVerifique los datos ingresados.","ERROR",2);
        }
     }

    public DefaultTableModel obtenerProducto(DefaultTableModel datos,String codigo){

        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerTupla("producto","id_producto",codigo);
            if (rs.next())
            {
                //imprimimos todos los datos contenidos en la tabla
                String [] producto = {
                    rs.getString (2),
                    rs.getString (3),
                    rs.getString (4),
                    rs.getString (5),
                    rs.getString (6)
               };
               datos.addRow(producto);
            }
            else
            {
                JOptionPane.showMessageDialog(null,"El producto solicitado no existe...\nVerifique el código ingresado.","ERROR",2);
            }
            x.cierraConexion();
            return datos;
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null,"Para ver los datos de un producto debe ingresar su código...\nVerifique los datos ingresados.","ERROR",2);
            return datos;
        }
    }

    public DefaultTableModel obtenerProductos(DefaultTableModel datos) {

        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerTuplaOrdenada("producto","nombre");
            while (rs.next())
            {
                //imprimimos todos los datos contenidos en la tabla
                Object [] empleado = {
                    new Integer(rs.getString (1)),
                    rs.getString (2),
                    rs.getString (3),
                    new Float(rs.getString (4)),
                    rs.getString (5),
                    new Integer(rs.getString (6))
               };
               datos.addRow(empleado);
            }
            x.cierraConexion();
            return datos;
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
        }
        return datos;
     }

    public DefaultTableModel obtenerProductosDonde(DefaultTableModel datos,String nombre) throws Exception{
        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerTupla("producto",nombre);
            while (rs.next())
            {
               String [] producto = {
                    rs.getString (1),
                    rs.getString (2),
                    rs.getString (3),
                    rs.getString (6),
                    rs.getString(5),
                    rs.getString (4)
               };
                datos.addRow(producto);
            }
            x.cierraConexion();

            return datos;
        }
        catch(Exception e)
        {
            throw e;
        }
    }




    public DefaultTableModel obtenerVolumenVentas(DefaultTableModel datos,java.sql.Date fecha1, java.sql.Date fecha2) throws Exception{
        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerVolumen(fecha1,fecha2);
            while (rs.next())
            {
             
               // (verificar)
               Object [] volumen = {
                    new Integer(rs.getString (1)),
                    rs.getString (2),
                    rs.getString (3),
                    rs.getString (4),
                    new Integer(rs.getString (5)),
                    new Float(rs.getString (6))
               };
               datos.addRow(volumen);
            }
            x.cierraConexion();

            return datos;
        }
        catch(Exception e)
        {
            throw e;
        }
    }


    /**
     * Devuelve todos los datos del cliente que verifican la busqueda en la base de datos
     * @param datos es  la tabla donde se almacenarán los datos del cliente
     * @return
     */
    public DefaultTableModel obtenerClientes(DefaultTableModel datos, String nombre){
        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerTupla("cliente","nombre_o_razon_social",nombre);
            while (rs.next())
            {
                //imprimimos todos los datos contenidos en la tabla
                Object [] cliente = {
                    
                    rs.getString (2),
                    rs.getString (3),
                    rs.getString (4),
                    rs.getString (5),
                    rs.getString (6),
                    rs.getString (7),
                    rs.getString (8),
                    rs.getString (9),
                    rs.getString (10),
                    rs.getString (11),
                    rs.getString (12)
               };
               datos.addRow(cliente);
            }
            x.cierraConexion();
            return datos;
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
        }
        return datos;
    }


    public DefaultTableModel obtenerClientesMinoristas(DefaultTableModel datos){
        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerTupla("cliente","cuit","","nombre_o_razon_social");
            while (rs.next())
            {
                //imprimimos todos los datos contenidos en la tabla
                Object [] cliente = {
                    rs.getString (2),
                    rs.getString (4),
                    rs.getString (6),
                    rs.getString (7),
                    rs.getString (8),
                    rs.getString (9),
                    rs.getString (12)
               };
               datos.addRow(cliente);
            }
            x.cierraConexion();
            return datos;
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
        }
        return datos;
    }

    public DefaultTableModel obtenerClientesMayoristas(DefaultTableModel datos){
        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerTupla("cliente","dni","nombre_o_razon_social",(Integer) null);
            while (rs.next())
            {
                //imprimimos todos los datos contenidos en la tabla
                Object [] cliente = {
                    rs.getString (2),
                    rs.getString (3),
                    rs.getString (5),
                    rs.getString (6),
                    rs.getString (7),
                    rs.getString(8),
                    rs.getString (9),
                    rs.getString (10),
                    rs.getString (11),
                    rs.getString (12)
               };
               datos.addRow(cliente);
            }
            x.cierraConexion();
            return datos;
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
        }
        return datos;
    }

    public DefaultComboBoxModel obtenerUsuarios(DefaultComboBoxModel modelo){

        ResultSet rs = null;
        Conexion x = new Conexion() ;
        x.estableceConexion();  //establece la conexion con la base de datos

        try{
            rs = x.obtenerTupla("empleado");
            while (rs.next())
            {
                String nombreUsuario = rs.getString (2);
                modelo.addElement(nombreUsuario);
            }
            x.cierraConexion(); //cierra la conexion con la base de datos
        }
        catch(Exception e)
        {
            JOptionPane.showMessageDialog(null,"Hubo un problema al acceder a la base de empleados...", "ERROR: ", 2);
        }
         return modelo;
    }

    /**
     * Permite obtener los datos de un usuario a partir de su nombre
     * @param datos el modelo de la tabla de usuarios
     * @return nombre_usuario de tabla con los datos del usuario
     * @throws Exception
     */
    public DefaultTableModel obtenerEmpleado(DefaultTableModel datos,String nombre_usuario) throws Exception {

        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
            rs = x.obtenerTupla("empleado","nombre_usuario",nombre_usuario);
            if (rs.next())
            {
                //imprimimos todos los datos contenidos en la tabla
                String [] empleado = {
                    rs.getString (1),
                    rs.getString (2),
                    rs.getString (4),
                    rs.getString (5),
                    rs.getString (6),
                    rs.getString (7),
                    rs.getString (8),
                    rs.getString (9)
               };
               datos.addRow(empleado);
            }
            else
            {
                JOptionPane.showMessageDialog(null,"El empleado ingresado no existe...\nVerifique el DNI ingresado.","ERROR",2);
            }
            x.cierraConexion();
            return datos;
        }
        catch(Exception e)
        {
            throw e;
        }
    }

    public DefaultTableModel obtenerDetalleVenta(DefaultTableModel datos,String nro_ticket) throws Exception{

        ResultSet rs = null;
        Conexion x = new Conexion() ;
        boolean entro = false;

        x.estableceConexion();
        try{
            rs = x.obtenerTupla(Integer.parseInt(nro_ticket));

            
            while (rs.next())
            {
                    entro = true;
                    String [] venta = {
                        rs.getString (1),
                        rs.getString (2),
                        rs.getString (3),
                        rs.getString (4),
                        rs.getString (5)
                    };
                    datos.addRow(venta);
            }
            if (!entro)
                throw new Exception();


            
            x.cierraConexion();
            return datos;
        }
        catch(Exception e)
        {
            throw e;
        }
    }
    
    public void obtenerDatosTicket(String nro_ticket, JLabel nroTicket, JLabel fechaTicket, JLabel horaTicket) throws Exception{
        ResultSet rs = null;
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try{
          //  rs = x.obtenerTupla("ticket","nro_ticket",Integer.parseInt(nro_ticket),"anulado","FALSE");
             rs = x.obtenerTupla("ticket","nro_ticket",Integer.parseInt(nro_ticket));
            if (rs.next())
            {
                if( rs.getBoolean(5))
                {
                   throw new TicketAnuladoExcepcion() ;
                }


                Date fecha = rs.getDate(3);
                SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
                String nuevaCadena = sdf.format(fecha);
                    
                nroTicket.setText(nroTicket.getText()+" "+rs.getString(1));
                fechaTicket.setText(fechaTicket.getText()+" "+nuevaCadena);
                horaTicket.setText(horaTicket.getText()+" "+rs.getString(2));
            }
            else
                throw new Exception();


            x.cierraConexion();
        }
        catch(Exception e)
        {
            throw e;
        }
        
        
    }



     /****************************************************************************
     *  Fin métodos para manipular BASE DE DATOS                                 *
     * **************************************************************************
     */

    /*****************************************************************************
     *  Métodos para validar datos del programa                                  *
     * ***************************************************************************
     */

    public boolean validarCamposLogin(String nombre_usuario,String password){
         //validacion de formularios vacios
        if ( nombre_usuario.equals("") && password.equals(""))
        {
            JOptionPane.showMessageDialog(null, "Los campos están vacios. Debe ingresar su nombre de usuario y su contraseña", "Advertencia", 2);
            return false;
        }

        if( nombre_usuario.equals("") )
        {
            JOptionPane.showMessageDialog(null, "El campo Usuario es obligario. Debe ingresar su nombre de usuario", "Advertencia", 2);
            return false;
        }

        if( password.equals("") )
        {
            JOptionPane.showMessageDialog(null, "El campo Contraseña es obligario. Debe ingresar su contraseña", "Advertencia", 2);
            return false;
        }

        return true;
    }

    /**
     *  verifica que no existan campos vacios en el formulario de creación de un nuevo empleado
     * @param vistaUsuario
     * @return
     */
    public boolean validarCamposCrearEmpleado(VistaUsuario vistaUsuario)
    {
        //verificamos si los camppos están vacíos
        if ( vistaUsuario.dni.getText().equals("") || vistaUsuario.usuario.getText().equals("")
             || vistaUsuario.calle.getText().equals("") || vistaUsuario.telefono.getText().equals("")
             || vistaUsuario.numero.getText().equals("") || vistaUsuario.verificaContraseña.getText().equals("")
             || vistaUsuario.contraseña.getText().equals("") || vistaUsuario.depto.getText().equals("") && !vistaUsuario.piso.getText().equals("")
             || !vistaUsuario.depto.getText().equals("") && vistaUsuario.piso.getText().equals(""))
        {
            JOptionPane.showMessageDialog(vistaUsuario, "Hay campos que están vacios. Por favor verifiquelo, y vuelva a intentarlo nuevamente", "ERROR", 2);
            return false;
        }
        else
            return true;
        
    }

    /**
     * Valida que el nro de dni no esté registrado en la base de datos, y esté entre los valores adecuados de un DNI
     *
     * @param vistaUsuario
     * @return el número de DNI
     * @throws Exception
     */
    private int validarDNI(VistaUsuario vistaUsuario) throws Exception{
        
        ResultSet rs = null;
        Conexion x = new Conexion() ;
        
        int dni=0;

        try{
                dni = Integer.parseInt(vistaUsuario.dni.getText());
                 
                if (dni < 1000000)
                {
                       throw new DniLongitudInferiorExcepcion();
                }
                if (dni > 99999999)
                {
                       throw new DniLongitudSuperiorExcepcion();
                }
                
                x.estableceConexion();
                try {
                    rs = x.obtenerTupla("empleado","dni",vistaUsuario.dni.getText());
                    x.cierraConexion();
                    if (rs.next())
                    {
                        //System.out.print("el nombre de usuario es" + nombreUsuario);
                        throw new DniExcepcion();
                    }
                    else
                    {
                        return dni;
                    }
                }
                catch (Exception ex) {
                    throw ex;
                }
        }
        catch (NumberFormatException e)
        {
             throw new DniFormatoIncorrectoExcepcion();
        }
    }

    /**
     * Verifica que el nombre de usuario no este registrado
     * @param vistaUsuario
     * @return
     * @throws Exception
     */
    private String validarUsuario(VistaUsuario vistaUsuario) throws Exception{

        Conexion x = new Conexion() ;   // esta linea establece la conexion con la base de datos
        ResultSet rs = null;
        x.estableceConexion();
        String nombreUsuario = vistaUsuario.usuario.getText().trim();

        try {
            rs = x.obtenerTupla("empleado","nombre_usuario",nombreUsuario);
            x.cierraConexion();
            if (rs.next())
            {
                throw new NombreUsuarioExcepcion();
            }
            else
            {
                System.out.print("el nombre de usuario es" + nombreUsuario);
                return nombreUsuario;
            }
        }
        catch (SQLException e){
            x.cierraConexion();
            throw e;
        }
     }

    /**
      * valida que el usuario no haya equivocado en el reingreso de la contraseña
      * @param vistaUsuario
      * @return
      * @throws ContraseñaIncorrectaExcepcion
      */
    private String validarContraseña (VistaUsuario vistaUsuario) throws ContraseñaIncorrectaExcepcion
    {
        if ( vistaUsuario.verificaContraseña.getText().equals( vistaUsuario.contraseña.getText() ) )
            return vistaUsuario.verificaContraseña.getText();
        else
            throw new ContraseñaIncorrectaExcepcion("La contraseña ingresada no se corresponde con la anterior");
    }

    /**
     * Valida que la función ingresada por el usuario sea correcta, pudiendo existir un único Gerente y más de un Administrador
     * y empleado de ventas.
     * @param vistaUsuario
     * @return
     * @throws EmpleadoExcepcion
     */
    private String validarFuncion(String funcion) throws Exception
    {
        Conexion x = new Conexion() ;   // esta linea establece la conexion con la base de datos
        ResultSet rs = null;
        x.estableceConexion();

        if (funcion.equals("empleado de ventas"))
            return funcion;

        try {
            rs = x.obtenerTupla("empleado","funcion",funcion);
            x.cierraConexion();
            if ( rs.next() )        //ya existe el gerente
            {
                if ( funcion.equals("gerente") )
                    throw new GerenteExcepcion();
                else
                    throw new AdministradorExcepcion();
            }
            else 
                return funcion;
        }
        catch (SQLException e){
            x.cierraConexion();
            throw e;
        }
    }

    public int validarNumeroCalle( VistaUsuario vistaUsuario ) throws NumeroFormatoIncorrectoExcepcion
    {
        String numero = vistaUsuario.numero.getText().trim();
        try
        {
           int num = Integer.parseInt(numero);
           return num;

        }
        catch (Exception e)
        {
             throw new NumeroFormatoIncorrectoExcepcion();
        }
    }

    private boolean validarFormularioCliente(VistaLaBaguette vistaLaBaguette)
    {
        String depto = vistaLaBaguette.campoDepto.getText().trim();
        String piso = vistaLaBaguette.campoPiso.getText().trim();
        if ( (depto.isEmpty() && !piso.isEmpty()) || (piso.isEmpty() && !depto.isEmpty()) )
        {
             JOptionPane.showMessageDialog(null, "El campo de piso o departamento están vacios. Por favor verifiquelo, y vuelva a intentarlo nuevamente", "ERROR", 2);
            return false;
        }

        return true;
    }

    private boolean validarFormularioClienteMayorista(VistaLaBaguette vistaLaBaguette)
    {
        String depto = vistaLaBaguette.campoDepto.getText().trim();
        String piso = vistaLaBaguette.campoPiso.getText().trim();

        if ( (depto.isEmpty() && !piso.isEmpty()) || (piso.isEmpty() && !depto.isEmpty()) )
        {
            JOptionPane.showMessageDialog(null, "El campo de piso o departamento están vacios. Por favor verifiquelo, y vuelva a intentarlo nuevamente", "ERROR", 2);
            return false;
        }

        return true;
    }

    /****************************************************************************
     *  Fin métodos para validar datos del programa                             *
     * **************************************************************************
     */
    
    /****************************************************************************
     *  Métodos para gestionar operaciones en curso                             *
     * **************************************************************************
     */

    public static boolean isHayOperacionEnCurso() {
        return hayOperacionEnCurso;
    }

    public static void setHayOperacionEnCurso(JFrame ventanaActiva) {
        Panaderia.hayOperacionEnCurso = true;
        Panaderia.ventanaActiva = ventanaActiva;
    }

     public static void setHayOperacionEnCurso(boolean operacion) {
        Panaderia.hayOperacionEnCurso = operacion;
    }

    public static JFrame getVentanaActiva() {
        return ventanaActiva;
    }

    public static boolean isHayVentaEnCurso() {
        return hayVentaEnCurso;
    }

    public static void setHayVentaEnCurso(boolean hayVentaEnCurso) {
        Panaderia.hayVentaEnCurso = hayVentaEnCurso;
    }

    

    /****************************************************************************
     *  Fin métodos para gestionar operaciones en curso                         *
     * **************************************************************************
     */

    /****************************************************************************
     *  Métodos para gestionar operaciones del local                            *
     * **************************************************************************
     */

    public void registrarVenta(VistaLaBaguette vista) throws Exception{

        final int porcentaje_maximo= 3;     //indica el porcentaje máximo de diferencia entre el efectivo ingresado y lo solicitado

        try{
            if (vista.campoEfectivo.getText().isEmpty())
                throw new EfectivoVacioExcepcion("No se ingreso efectivo.");

            float total = new Float(vista.jLabel46.getText().substring(2)); 
            float efectivo = new Float(vista.campoEfectivo.getText().trim());

            if (efectivo > total * porcentaje_maximo) // Verificamos si el efectivo ingresado es superior al 300%
            {
                int opcion;
                opcion = JOptionPane.showConfirmDialog(vista, "El efectivo ingresado para procesar la transacción es mucho\nEsta seguro que quiere continuar?.", "Cuidado!", JOptionPane.YES_NO_OPTION);
                if (opcion != 0)
                    return;
            }

            NumberFormat nf = NumberFormat.getInstance(Locale.UK);
            nf.setMinimumFractionDigits(2);

            vista.etiquetaEfectivo.setText("$ "+nf.format(efectivo));
            float cambio = efectivo - total;
            if (cambio < 0)
                throw new EfectivoInsuficienteExcepcion("Faltan $"+Math.abs(cambio));
            
            vista.etiquetaCambio.setText("$ "+nf.format(cambio));
         
        }
        catch (Exception e){
            if (e instanceof NumberFormatException)
            {
                throw new EfectivoIncorrectoExcepcion("El efectivo debe ser un monto ($).\nLa parte entera debe separarse con un punto de la fraccionaria");
            }

            if (e instanceof ParseException )
            {
                throw new EfectivoIncorrectoExcepcion("A ingresado en efectivo un valor que no es un número");
            }

            throw e;
        }

    }

    public void registrarV(VistaLaBaguette vista){
          try {
            for (int i = 0; i < vista.tablaDetalleProducto.getRowCount(); i++) {
                this.actualizarStock(vista.tablaDetalleProducto.getValueAt(i, 0).toString(), vista.tablaDetalleProducto.getValueAt(i, 3).toString());
            }

            Conexion x = new Conexion();
            x.estableceConexion();
            int nro_ticket = Integer.parseInt(x.obtenerID("nro_ticket", "ticket"));
            ++nro_ticket;
            x.cierraConexion();
            Ticket ticket = new Ticket(nro_ticket);
            this.crearTicket(ticket.getHora(), ticket.getFecha());
            int codigo;
            int cantidad;
            float precio_unitario;
            //creamos el detalle del ticket
            for (int j = 0; j < vista.tablaDetalleProducto.getRowCount(); j++) {
                int renglon = j + 1;
                codigo = Integer.parseInt(vista.tablaDetalleProducto.getValueAt(j, 0).toString());
                cantidad = Integer.parseInt(vista.tablaDetalleProducto.getValueAt(j, 3).toString());
                precio_unitario = Float.parseFloat(vista.tablaDetalleProducto.getValueAt(j, 4).toString()) / cantidad;
                this.crearDetalleTicket(ticket.getNro_ticket(), codigo, renglon, precio_unitario, cantidad);
            }

            JOptionPane.showMessageDialog(vista, "Se registro la venta...", "OK", 1);
            vista.campoEfectivo.setText("");
            vista.limpiarVenta();
            vista.botonRegistrar.setEnabled(false);
            vista.botonAgregar.setEnabled(true);
            vista.campoProducto.setEnabled(true);
            vista.campoCantidad.setEnabled(true);
            vista.campoEfectivo.setEnabled(true);
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(vista, "Hubo un problema al obtener el número de ticket", "ERROR", 2);
        }
    }


    public void actualizarStock(String codigo,String cantidad){
        Conexion x = new Conexion() ;

        x.estableceConexion();
        try {
            x.modificarRegistro(Integer.parseInt(codigo),cantidad);
        }
        catch (Exception ex) {
                JOptionPane.showMessageDialog(null,"Hubo un problema al intentar modificar el producto...\nEl codigo de producto no puede ser modificado"+ex.getMessage(),"ERROR",2);
        }
        x.cierraConexion();
    }


    /**
     * Registra la devolecion de dinero correspondiente a una venta efectuada. Lo realizando anulando el ticket de la compra y generando un
     * nuevo ticket por los productos restantes de la compra, si es que los ubiese. De lo contrario solo se anula el ticket.
     * @param vista
     * @throws Exception
     */
    public void registrarDevolucionDinero(VistaLaBaguette vista)
    {
        int codigo;                             //codigo del producto de un renglon del ticket
        int cantidad;                           //cantidad del producto de un renglon
        float precio_unitario;                  //precio unitario del producto de un renglon

        try{

            Conexion x = new Conexion();
            x.estableceConexion();
            int nro_ticket = Integer.parseInt(x.obtenerID("nro_ticket", "ticket"));
            ++nro_ticket;
            x.cierraConexion();
            Ticket ticket = new Ticket(nro_ticket);
            this.anularTicket(Integer.parseInt(vista.numero2.getText().trim() ) );

            if( vista.jTable3.getRowCount() == 0 ) // si no quedo ningun articulo de la venta ==> no generar nuevo ticket
                return;

            //de lo contrario procedemos a crear un nuevo ticket


            this.crearTicket(ticket.getHora(), ticket.getFecha());
            //creamos el detalle del ticket
            for (int j = 0; j < vista.jTable3.getRowCount(); j++)
            {
                int renglon = j + 1;
                codigo = Integer.parseInt(vista.jTable3.getValueAt(j, 0).toString());
                cantidad = Integer.parseInt(vista.jTable3.getValueAt(j, 3).toString());
                precio_unitario = Float.parseFloat(vista.jTable3.getValueAt(j, 4).toString()) / cantidad;
                this.crearDetalleTicket(ticket.getNro_ticket(), codigo, renglon, precio_unitario, cantidad);
            }
         }
         catch (Exception ex) {
            JOptionPane.showMessageDialog(vista, "Hubo un problema al obtener el número de ticket", "ERROR", 2);
        }
    }


    public boolean registrarBajaDrastica() {
        return true;
    }

    public boolean listarVentasPorPeriodo() {
        return true;
    }

    private void crearTicket(java.sql.Time hora, java.sql.Date sqlFecha) {
        Conexion x = new Conexion();
        ResultSet rs = null;
        x.estableceConexion();

        try {
             x.crearRegistro(hora,sqlFecha); //crea el ticket

        }
        catch (Exception ex) {
            if( ex instanceof SQLException)
                JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
            else
                System.out.println("hubo otro tipo de excepciones "+ex.getMessage() );
        }
        // Esta linea cierra la conexion con la base de datos
        x.cierraConexion();

    }

    private void crearTicket(int nro_ticket, String hora, java.sql.Date sqlFecha,int id_cliente) {


    }

    private void crearDetalleTicket( int nro_ticket,int id_producto, int nro_renglon, float precio_unitario , int cantidad )
    {
        Conexion x = new Conexion();
        x.estableceConexion();

        try {
            x.crearRegistro(nro_renglon, nro_ticket, id_producto,cantidad, precio_unitario);
        }
        catch(Exception ex){
            if( ex instanceof SQLException)
                JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
            else
                System.out.println("hubo otro tipo de excepciones "+ex.getMessage() );
        }
    }


    /**
     * anula un ticket
     * @param nro_ticket el número de ticket a anular
     */
    private void anularTicket(int nro_ticket)
    {
      Conexion x = new Conexion();
        x.estableceConexion();

        try {
            x.modificarRegistro(nro_ticket);
        }
        catch(Exception ex){
            if( ex instanceof SQLException)
                JOptionPane.showMessageDialog(null,"El tipo de dato ingresado no es correcto...\nVerifique los tipos de datos ingresados","ERROR",2);
            else
                System.out.println("hubo otro tipo de excepciones "+ex.getMessage() );
        }
    }


    /****************************************************************************
     * Fin métodos para gestionar operaciones del local                         *
     * **************************************************************************
     */
}
